package ex.hql.config;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import ex.hql.pojo.MailConstants;
import ex.hql.pojo.MailLog;
import ex.hql.service.IMailLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @program:yeb
 * @author: hql
 * @Time: 2021/9/5  16:34
 * @description: rabbit配置类
 */
@Configuration
public class RabbitMqConfig {

    private static final Logger logger= LoggerFactory.getLogger(RabbitMqConfig.class);

    @Autowired
    private CachingConnectionFactory cachingConnectionFactory;

    @Autowired
    private IMailLogService mailLogService;

    @Bean
    public Queue queue(){
        return new Queue(MailConstants.MAIL_QUEUE_NAME);
    }

    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange(MailConstants.MAIL_EXCHANGE_NAME);
    }

    @Bean
    public Binding binding(){
        return BindingBuilder.bind(queue()).to(directExchange()).with(MailConstants.MAIL_ROUTING_KEY_NAME);
    }

    @Bean
    public RabbitTemplate rabbitTemplate(){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
        //消息确认回调，确认消息是否到达broker
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             * @param correlationData：对象内部只有一个 id 属性，用来表示当前消息的唯一性。
             * @param ack 消息投递到broker 的状态，true表示成功。
             * @param cause 表示投递失败的原因。
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                String msgID = correlationData.getId();
                if(ack){
                        logger.info("{}============>消息发送成功",msgID);
                        mailLogService.update(new UpdateWrapper<MailLog>().set("status",1).eq("msgId",msgID));
                    }else {
                    logger.error("{}===========>消息发送失败",cause);
                }
            }
        });

        //消息失败回调
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {

            /**
             * message（消息体）、replyCode（响应code）、replyText（响应内容）、exchange（交换机）、routingKey（队列）
             * @param returnedMessage
             */
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                logger.error("{}===========>消息发送失败",returnedMessage.getMessage());
            }
        });


        return rabbitTemplate;
    }




}
